#!/usr/bin/perl -w

#
#NOTES: 
#
# use \savebox to make numbers align??
# use fractions for all computations
# add Nine Chapters problems w/ drop down menu

#
#PERL MODULES
#

use strict;
use CGI qw/:standard/;
#use CGI qw/-no_undef_params -nosticky :all/;
use CGI::Carp qw(fatalsToBrowser);

#
#VARIABLES
#

my $query = new CGI; 
my $formattedtabledata;
my %a;
my %b;
my %c;
my %num;
my %denom;
my %sign;
my @JZSS = "";
my @JZSSproblems = "";
my $N = "";
my $M = "";
my $matrix = "";
my $cmatrix = "";
my @matrices = "";
my @cmatrices = "";
my @abstractmatrices = "";
my @result = "";
my $denominator;
my @cresult = "";
my $cintegers = 1;
my $error = "";
my $pm = "";
my $pm1 = 1;
my $noninteger = 0;
my $usegcf =0;
my $JZSSnum = "";
my $reducetens = 1;
my @formula = "";
my @boardnotes = "";
my @calcnotes = "";
my @formulanotes = "";
my $output;
my $table_a = ""; 
my $table_header = ""; 
my $print_a = "";
my @frac;
my $inputerror = "";

#
#MATRICES
#

#JZSS
#3
$JZSS[1] = [["2", "1", "0", "1"], ["0", "3", "1", "1"], ["1", "0", "4", "1"]];
#12
$JZSS[2] = [["1", "1", "0", "40"], ["0", "2", "1", "40"], ["1", "0", "3", "40"]];
#13
$JZSS[3] = [["2", "1", "0", "0", "0", "721"], ["0", "3", "1", "0", "0", "721"], ["0", "0", "4", "1", "0", "721"], ["0", "0", "0", "5", "1", "721"], ["1", "0", "0", "0", "6", "721"]];
#15
$JZSS[4] = [["2", "-1", "0", "1"], ["0", "3", "-1", "1"], ["-1", "0", "4", "1"]];

# YHJZSS
$JZSS[5] = [["2", "1", "0", "2500"], ["0", "3", "1", "2500"], ["1", "0", "4", "2500"]];

#SXZJ
$JZSS[6] = [["15", "1670", "0", "0", "106000"], ["0", "800", "264", "0", "106000"], ["0", "0", "40", "200", "106000"], ["52", "0", "0", "175/3", "106000"]];

#744.4
$JZSS[7] = [["2", "1", "0", "1"], ["0", "3", "1", "1"], ["1", "0", "4", "2"]];

#747.3
$JZSS[8] = [["4", "-1", "0", "300"], ["0", "5", "-1", "300"], ["-1", "0", "6", "300"]];

#750.2
$JZSS[9] = [["2", "4", "0", "0", "40"], ["0", "2", "7", "0", "40"], ["0", "0", "4", "7", "30"], ["1", "0", "0", "8", "24"]];

#SFTZ
#4**
$JZSS[10] = [["1", "1", "0", "42"], ["0", "2", "1", "42"], ["1", "0", "3", "42"]];
#5**
$JZSS[11] = [["2", "3", "0", "2040"], ["0", "5", "6", "640"], ["3", "0", "7", "2980"]];
#8**
$JZSS[12] = [["2", "4", "0", "0", "40"], ["0", "2", "7", "0", "40"], ["0", "0", "4", "7", "30"], ["1", "0", "0", "8", "24"]];

#359.3
$JZSS[13] = [["10", "1", "0", "0", "1"], ["0", "10", "2", "0", "1"], ["0", "0", "10", "3", "1"], ["4", "0", "0", "10", "1"]];

#366.4
$JZSS[14] = [["1", "1", "0", "42"], ["0", "2", "1", "42"], ["1", "0", "3", "42"]];

#372.3
$JZSS[15] = [["2", "4", "0", "0", "40"], ["0", "2", "7", "0", "40"], ["0", "0", "4", "7", "30"], ["1", "0", "0", "8", "24"]];

#373.3
$JZSS[16] = [["1", "8", "0", "0", "24"], ["0", "7", "4", "0", "30"], ["0", "0", "7", "2", "40"], ["2", "0", "0", "4", "40"]];

#374.1
$JZSS[17] = [["2", "7", "0", "0", "40"], ["0", "4", "7", "0", "30"], ["0", "0", "8", "1", "24"], ["4", "0", "0", "2", "40"]];

$JZSS[18] = [["1", "1/3", "0", "0", "0", "1442"], ["0", "1", "1/4", "0", "0", "1442"], ["0", "0", "1", "1/5", "0", "1442"], ["0", "0", "0", "1", "1/6", "1442"], ["1/2", "0", "0", "0", "1", "1442"]];

$JZSS[19] = [["1", "-1/3", "0", "0", "0", "719"], ["0", "1", "-1/4", "0", "0", "719"], ["0", "0", "1", "-1/5", "0", "719"], ["0", "0", "0", "1", "-1/6", "719"], ["-1/2", "0", "0", "0", "1", "719"]];

$JZSS[20] = [["1", "-1/3", "0", "0", "0", "0"], ["0", "1", "-1/4", "0", "0", "0"], ["0", "0", "1", "-1/5", "0", "0"], ["0", "0", "0", "1", "-1/6", "0"], ["1/2", "0", "0", "0", "1", "721"]];

$JZSS[21] = [["10", "1", "0", "0", "9976"], ["0", "10", "2", "0", "9976"], ["0", "0", "10", "3", "9976"], ["4", "0", "0", "10", "9976"]];

$JZSS[22] = [["2/5", "1", "0", "6780"], ["0", "2/3", "1", "6780"], ["1", "0", "2/7", "6780"]];

$JZSS[23] = [["3", "30", "0", "0", "0", "0", "0", "0", "0", "45"], ["0", "30", "-120", "0", "0", "0", "0", "0", "0", "0"], ["0", "0", "100", "-50", "0", "0", "0", "0", "0", "0"], ["0", "0", "0", "30", "30", "0", "0", "0", "0", "18"], ["0", "0", "0", "0", "50", "10", "0", "0", "0", "45"], ["0", "0", "0", "0", "0", "15", "17", "0", "0", "111/2"], ["0", "0", "0", "0", "0", "0", "20", "-40", "0", "28"], ["0", "0", "0", "0", "0", "0", "0", "20", "-10", "0"], ["2", "0", "0", "0", "0", "0", "0", "0", "80", "34"]];

@JZSSproblems = (1..23);

#
#  SUBROUTINES
#

#LOAD MATRIX SUBROUTINES

sub nofractions {
	foreach my $n (1..$N){
		foreach my $m (1..$M){
			if ($a{$n}{$m} =~m/(\d+)\/(\d+)/){
				my $num = $1;
				my $denom = $2;
				my $gcf = &gcf($num,$denom);
				$num /= $gcf;
				$denom /= $gcf;
				foreach my $p (1..$M) {
					$a{$n}{$p} *= $denom;
				}
			}
		}
	}
}

sub JZSS {
 	my ($t) = @_;
	$N = $#{$JZSS[$t][0]}; 
	$M = $N + 1;
	my $i = 1;
	my $j =1;
	foreach my $n (1..$N) {
		foreach my $m (1..$M) {
			$b{$n}{$m} = $JZSS[$t][$n-1][$m-1];
			if ($JZSS[$t][$n-1][$m-1] =~s/^-//){ 
				$sign{$n}{$m} = -1;  
			}else{
				$sign{$n}{$m} = 1;  
			}
			if (($JZSS[$t][$n-1][$m-1] == "") or ($JZSS[$t][$n-1][$m-1] =~ m/^0+$/)) { #blank or all zeros, possibly -
				$num{$n}{$m} = 0;
				$denom{$n}{$m} = 1;
				$sign{$n}{$m} = 1;
			}elsif ($JZSS[$t][$n-1][$m-1] =~ m/^(\d+)$/) {
				$num{$n}{$m} = $1;
				$denom{$n}{$m} = 1;
			}elsif ($JZSS[$t][$n-1][$m-1] =~m/^(\d+)\/(\d+)$/){
				$num{$n}{$m} =$1;
				$denom{$n}{$m} =$2;
				if ($denom{$n}{$m} == 0) {
					$denom{$n}{$m} = 1;
				}
				my $gcf = &gcf($num{$n}{$m},$denom{$n}{$m});
				$num{$n}{$m} /=$gcf || print "Divided by 0\n";
				$denom{$n}{$m} /=$gcf || print "Divided by 0\n";			
			}else{
				print "Error! \"$JZSS[$t][$n-1][$m-1]\" \n";
			}
		}
		my $lcm = 1;
		my $gcf = &gcf($denom{$n}{1},$denom{$n}{2});
		foreach my $m (3..$M) {
			$gcf = &gcf($gcf,$denom{$n}{$m});
		}
		foreach my $m (1..$M) {
			$lcm *= $denom{$n}{$m};
 			$lcm /= $gcf;
		}
		foreach my $m (1..$M) {
			unless ($denom{$n}{$m} == 0 ){
				$a{$n}{$m} = ($sign{$n}{$m} * $num{$n}{$m} * $lcm) / $denom{$n}{$m};
			}
		}
	}
	return %a;
}

sub random_a {
	foreach my $n (1..$N) {
		foreach my $m (1..$N) {
			$a{$n}{$m} =  int(rand(8))+1;
		}
	$a{$n}{$N+1} =  int(rand(149))+1;
	}
}

# MATRIX CALCULATION SUBROUTINES

sub noninteger {
	$noninteger = 0;
	foreach my $n (1..$N) {
		foreach my $m (1..$M) {
			if ($a{$n}{$m} != int($a{$n}{$m})) {$noninteger = 1};
		}
	}
	return $noninteger;
}

sub pm {
	my ($n) = @_;
	if ($n % 2 == 0) {$pm = "+"} else {$pm = "-"};
	return $pm;
}

sub pm1 {
	my ($n) = @_;
	if ($n % 2 == 0) {$pm1 = 1} else {$pm1 = -1};
	return $pm1;
}


sub determinants {
	&nofractions;
	$matrices[0] = &print_matrix;
	&num2rods;
	$cmatrices[0] = &print_cmatrix;
	&print_abstractmatrix(0);
	$boardnotes[0] .= qq{<p>Arranged on the counting board, we have:</p>};
	$calcnotes[0] .= qq{<p>This corresponds to the following augmented matrix:</p>};
	$formulanotes[0] .= qq{<p>Using variables, we can show what this corresponds to in terms of an exemplar:</p>};
	my $anN = $a{$N}{1};
	foreach my $n (2..$N-1) {
		$anN *= $a{$n-1}{$n};
		$a{$N}{$n} = &pm1($n-1) * $anN;
		$matrices[$n-1] = &print_matrix;
		&num2rods;
		$cmatrices[$n-1] = &print_cmatrix;
		&print_abstractmatrix($n-1);
	};	
	$formula[$N] = qq{ k_1 b_{$N} - l_{$N}b_1 };	
	$result[1] = $a{1}{1} * $a{$N}{$M} - $a{$N}{1} * $a{1}{$M} ;
	$cresult[1] = &onenum2rods($result[1]);
	foreach my $n (2..$N-1) {
		#calculate result
		$result[$n] = $result[$n-1];
		$result[$n] *= $a{$n}{$n};
		$result[$n] -= $a{$N}{$n} * $a{$n}{$M} ;
		#convert to cresult
		$cresult[$n] = &onenum2rods($result[$n]);
		#create formula
		$formula[$N+$n-1] = "(" . $formula[$N-2+$n];
		my $r = $N-$n+1; 
		&pm($n);
		$formula[$N+$n-1] .= qq{ ) k_{$n}  $pm };
		my $s = $n -1;
		$formula[$N+$n-1] .= qq{ l_{$N} };
		foreach my $i (1..$n -1) {
			if ($i < $n -1 ) {
				$formula[$N+$n-1] .= qq{ l_{$i}  };
			}
		}
		$formula[$N+$n-1] .= qq{ l_{$s} b_{$n} };
	};
	#calculate result
	$denominator = 1;
	foreach my $n (1..$N) {
		$denominator *= $a{$n}{$n};
	}
	my $subtractand = -$a{$N}{1};
	foreach my $n (1..$N-1) {
		$subtractand *= -$a{$n}{$n+1};
	}
	$denominator -= $subtractand;
	&frac(1,0,$result[$N-1],$denominator);
	$result[$N] = "x_{$N} = ";
	if ($frac[2] == 0) {
		$result[$N] .= $frac[0] * $frac[1];
	}else{
		if ($frac[0] == 1) {
			$result[$N] .= "\\frac{$frac[2]}{$frac[3]}"		
		}else{
			$result[$N] .= "-\\frac{$frac[2]}{$frac[3]}"				
		}
		#$result[$N] = " \\text{ or } $mixedfrac[0]\\frac{$mixedfrac[1]}{$mixedfrac[2]}"
	}
	#convert to cresult
	#$cresult[$n] = &onenum2rods($result[$n]);
	#create formula
	my $denom = "";
	foreach my $n (1..$N) {
		$denom .= "k_{$n}";
	}
	$denom .= "$pm";
	foreach my $n (1..$N) {
		$denom .= "l_{$n}";
	}
	
	$formula[2*$N]	= "x_{$N} = \\frac{" . $formula[2*$N-2] . "}{$denom}}";
};

sub gcf {
  my ($x, $y) = @_;
  ($x, $y) = ($y, $x % $y) while $y;
  return $x;
}

sub reducetens {
	my ($n) = @_;
	if ($reducetens) {
		my $alltens = 1;
		while ($alltens) {
			foreach my $m (0..$M) {
				if (int($a{$n}{$m}/10) != ($a{$n}{$m}/10)) {
					$alltens = 0;				
				};
			}
			if ($alltens) {
				foreach my $m (1..$M) {
					$a{$n}{$m} = $a{$n}{$m} /10;
				}
			}
		}
	}
}


sub rowReduction {
	&nofractions;
	$matrices[0] = &print_matrix;
	&num2rods;
	$cmatrices[0] = &print_cmatrix;
	&print_abstractmatrix(0);
	$boardnotes[0] .= qq{<p>Arranged on the counting board, we have:</p>};
	$calcnotes[0] .= qq{<p>This corresponds to the following augmented matrix:</p>};
	$formulanotes[0] .= qq{<p>Using variables, we can show what this corresponds to in terms of an exemplar:</p>};
	foreach my $i (1..($N-1)) {
		if ($a{$i}{$i} != 0) { #need else: use another pivot
			foreach my $n (($i+1)..$N) {
				if ($a{$n}{$i} != 0){
					if ($a{$i}{$i} == $a{$n}{$i} ){
						foreach my $m ($i..$M) {
							$a{$n}{$m} = ($a{$n}{$m} - $a{$i}{$m});
						}
						&reducetens($n);
					} else {
						my $gcf = 1; 
						if ($usegcf) { $gcf = &gcf($a{$i}{$i},$a{$n}{$i}) };
						my $nmult = $a{$i}{$i}/$gcf;
						my $imult = $a{$n}{$i}/$gcf;
						foreach my $m (1..$M) {
							$a{$n}{$m} = $nmult*$a{$n}{$m} - $imult*$a{$i}{$m};
						}
						&reducetens($n);						
					}
				}
			}
		}
	$matrices[$i] = &print_matrix;
	&noninteger;
	&num2rods;
	$cmatrices[$i] = &print_cmatrix;
	}
}

sub backSubstitution {
	foreach my $i ( reverse (1..($N-1))) {
		my $bi = 0;
		$bi += $a{$N}{$N}*$a{$i}{$M};
		foreach my $j ( reverse (($i+1)..$N)) {
			$bi -= $a{$j}{$M}*$a{$i}{$j};
		}
		if ($a{$i}{$i} == 0 ) {
			$error .= "ann = $a{$i}{$i} for n = $i<p>";
		}else{
			$bi /= $a{$i}{$i};
			if (int($bi)!=$bi ) {
				$error .= "bi = $bi for n = $i<p>";	
			}
			$a{$i}{$M} = $bi;
			foreach my $k (reverse ($i..$N)) {
				$a{$i}{$k}=0;
			}			
		}
		&noninteger;
		$matrices[2*$N-$i] = &print_matrix;
		&num2rods;
		$cmatrices[2*$N-$i] = &print_cmatrix;			
	}
}

sub divideANN {
	foreach my $i ( reverse (1..$N)) {
		unless ($a{$N}{$N} == 0) {
			my $quot = $a{$i}{$M}/$a{$N}{$N};
			my $int =  int($quot);
			if ( $quot == $int ) {
				$a{$i}{$M} = $int;
			}else{
				my $denom = $a{$N}{$N};
				my $num = $a{$i}{$M} - int($quot)*$denom;
				my $gcf = &gcf($num, $denom);
				$num /= $gcf;
				$denom /= $gcf;
				if ($int == 0) {
					$int = "";
				}else{
					$num = abs($num);
					$denom = abs($denom);
				};
				$a{$i}{$M} = "$int\\frac{$num}{$denom}";
			}	
			if ($i ==1 ) {	$a{$N}{$N} = 0 }
			$matrices[3*$N-$i] = &print_matrix;
			&noninteger;
			unless (1==1) { #  $noninteger
				&num2rods;
				$cmatrices[3*$N-$i] = &print_cmatrix;		
			}
		}
	}
}

#Fraction subroutines

sub add {}

sub subtract {}

sub multiply {}

sub divide {}

sub reduce {}

sub frac {
	my ($sign,$int,$num,$denom) = @_;
	#put sign in $sign
	if ($int != abs($int)) {$int *= -1; $sign *= -1};
	if ($num != abs($num)) {$num *= -1; $sign *= -1};
	if ($denom != abs($denom)) {$denom *= -1; $sign *= -1};
	#calculate if fraction
	if ($num != 0){ 
		$num += $int*$denom;
		$int = 0;
		unless ($denom == 0) { #make sure not dividing by 0
			$int = int($num/$denom);
			if ( $num/$denom == $int ) { #if result is integer
				$num = 0;
				$denom = 1;
			}else{ 
				my $gcf = &gcf($num, $denom);
				$num /= $gcf;
				$denom /= $gcf;
			}	
		}
	}
	@frac = ($sign, $int, $num, $denom);
	return @frac;
}


#PRINT MATRIX SUBROUTINES

sub num2rods {
	unless ($noninteger) {
		foreach my $n (1..$N) {
			foreach my $m (1..$M) {
				my $number = "";
				$c{$n}{$m} = "";
				if ($a{$n}{$m} >= 0 ) {
					$number = $a{$n}{$m};
						while ( $number ne "" ) { 
						my $digit = "";
						$number =~s/\d$//;
						$digit = $&;
						$c{$n}{$m} = "~" . $c{$n}{$m};
						$c{$n}{$m} = "\\zero" . $c{$n}{$m} if $digit == 0;
						$c{$n}{$m} = "\\one" . $c{$n}{$m} if $digit == 1;
						$c{$n}{$m} = "\\two" . $c{$n}{$m} if $digit == 2;
						$c{$n}{$m} = "\\three" . $c{$n}{$m} if $digit == 3;
						$c{$n}{$m} = "\\four" . $c{$n}{$m} if $digit == 4;
						$c{$n}{$m} = "\\five" . $c{$n}{$m} if $digit == 5;
						$c{$n}{$m} = "\\six" . $c{$n}{$m} if $digit == 6;
						$c{$n}{$m} = "\\seven" . $c{$n}{$m} if $digit == 7;
						$c{$n}{$m} = "\\eight" . $c{$n}{$m} if $digit == 8;
						$c{$n}{$m} = "\\nine" . $c{$n}{$m} if $digit == 9;
						if ($number ne "") {
							my $ten = "";
							$number =~s/\d$//;
							$ten = $&;
							$c{$n}{$m} = "~" . $c{$n}{$m};
							$c{$n}{$m} = "\\zero" . $c{$n}{$m} if $ten == 0;
							$c{$n}{$m} = "\\ten" . $c{$n}{$m} if $ten == 1;
							$c{$n}{$m} = "\\twenty" . $c{$n}{$m} if $ten == 2;
							$c{$n}{$m} = "\\thirty" . $c{$n}{$m} if $ten == 3;
							$c{$n}{$m} = "\\forty" . $c{$n}{$m} if $ten == 4;
							$c{$n}{$m} = "\\fifty" . $c{$n}{$m} if $ten == 5;
							$c{$n}{$m} = "\\sixty" . $c{$n}{$m} if $ten == 6;
							$c{$n}{$m} = "\\seventy" . $c{$n}{$m} if $ten == 7;
							$c{$n}{$m} = "\\eighty" . $c{$n}{$m} if $ten == 8;
							$c{$n}{$m} = "\\ninety" . $c{$n}{$m} if $ten == 9;
						}
					}
				}else{
					$number = -$a{$n}{$m};
						while ( $number ne "" ) { 
						my $digit = "";
						$number =~s/\d$//;
						$digit = $&;
						$c{$n}{$m} = "~" . $c{$n}{$m};
						$c{$n}{$m} = "\\Zero" . $c{$n}{$m} if $digit == 0;
						$c{$n}{$m} = "\\One" . $c{$n}{$m} if $digit == 1;
						$c{$n}{$m} = "\\Two" . $c{$n}{$m} if $digit == 2;
						$c{$n}{$m} = "\\Three" . $c{$n}{$m} if $digit == 3;
						$c{$n}{$m} = "\\Four" . $c{$n}{$m} if $digit == 4;
						$c{$n}{$m} = "\\Five" . $c{$n}{$m} if $digit == 5;
						$c{$n}{$m} = "\\Six" . $c{$n}{$m} if $digit == 6;
						$c{$n}{$m} = "\\Seven" . $c{$n}{$m} if $digit == 7;
						$c{$n}{$m} = "\\Eight" . $c{$n}{$m} if $digit == 8;
						$c{$n}{$m} = "\\Nine" . $c{$n}{$m} if $digit == 9;
						if ($number ne "") {
							my $ten = "";
							$number =~s/\d$//;
							$ten = $&;
							$c{$n}{$m} = "~" . $c{$n}{$m};
							$c{$n}{$m} = "\\Zero" . $c{$n}{$m} if $ten == 0;
							$c{$n}{$m} = "\\Ten" . $c{$n}{$m} if $ten == 1;
							$c{$n}{$m} = "\\Twenty" . $c{$n}{$m} if $ten == 2;
							$c{$n}{$m} = "\\Thirty" . $c{$n}{$m} if $ten == 3;
							$c{$n}{$m} = "\\Forty" . $c{$n}{$m} if $ten == 4;
							$c{$n}{$m} = "\\Fifty" . $c{$n}{$m} if $ten == 5;
							$c{$n}{$m} = "\\Sixty" . $c{$n}{$m} if $ten == 6;
							$c{$n}{$m} = "\\Seventy" . $c{$n}{$m} if $ten == 7;
							$c{$n}{$m} = "\\Eighty" . $c{$n}{$m} if $ten == 8;
							$c{$n}{$m} = "\\Ninety" . $c{$n}{$m} if $ten == 9;
						}
					}
				}								
			#$c{$n}{$m} = "\\shoveright " . $c{$n}{$m};
			}
		}
	}
}


sub onenum2rods {
	my ($number) = @_;
	# unless ($noninteger) {}
	my $cresult = "";
	if ($number >= 0 ) {
		while ( $number ne "" ) { 
			my $digit = "";
			$number =~s/\d$//;
			$digit = $&;
			$cresult = "~" . $cresult;
			$cresult = "\\zero" . $cresult if $digit == 0;
			$cresult = "\\one" . $cresult if $digit == 1;
			$cresult = "\\two" . $cresult if $digit == 2;
			$cresult = "\\three" . $cresult if $digit == 3;
			$cresult = "\\four" . $cresult if $digit == 4;
			$cresult = "\\five" . $cresult if $digit == 5;
			$cresult = "\\six" . $cresult if $digit == 6;
			$cresult = "\\seven" . $cresult if $digit == 7;
			$cresult = "\\eight" . $cresult if $digit == 8;
			$cresult = "\\nine" . $cresult if $digit == 9;
			if ($number ne "") {
				my $ten = "";
				$number =~s/\d$//;
				$ten = $&;
				$cresult = "~" . $cresult;
				$cresult = "\\zero" . $cresult if $ten == 0;
				$cresult = "\\ten" . $cresult if $ten == 1;
				$cresult = "\\twenty" . $cresult if $ten == 2;
				$cresult = "\\thirty" . $cresult if $ten == 3;
				$cresult = "\\forty" . $cresult if $ten == 4;
				$cresult = "\\fifty" . $cresult if $ten == 5;
				$cresult = "\\sixty" . $cresult if $ten == 6;
				$cresult = "\\seventy" . $cresult if $ten == 7;
				$cresult = "\\eighty" . $cresult if $ten == 8;
				$cresult = "\\ninety" . $cresult if $ten == 9;
			}
		}
	}else{
		$number = -$number;
		while ( $number ne "" ) { 
			my $digit = "";
			$number =~s/\d$//;
			$digit = $&;
			$cresult = "~" . $cresult;
			$cresult = "\\Zero" . $cresult if $digit == 0;
			$cresult = "\\One" . $cresult if $digit == 1;
			$cresult = "\\Two" . $cresult if $digit == 2;
			$cresult = "\\Three" . $cresult if $digit == 3;
			$cresult = "\\Four" . $cresult if $digit == 4;
			$cresult = "\\Five" . $cresult if $digit == 5;
			$cresult = "\\Six" . $cresult if $digit == 6;
			$cresult = "\\Seven" . $cresult if $digit == 7;
			$cresult = "\\Eight" . $cresult if $digit == 8;
			$cresult = "\\Nine" . $cresult if $digit == 9;
			if ($number ne "") {
				my $ten = "";
				$number =~s/\d$//;
				$ten = $&;
				$cresult = "~" . $cresult;
				$cresult = "\\Zero" . $cresult if $ten == 0;
				$cresult = "\\Ten" . $cresult if $ten == 1;
				$cresult = "\\Twenty" . $cresult if $ten == 2;
				$cresult = "\\Thirty" . $cresult if $ten == 3;
				$cresult = "\\Forty" . $cresult if $ten == 4;
				$cresult = "\\Fifty" . $cresult if $ten == 5;
				$cresult = "\\Sixty" . $cresult if $ten == 6;
				$cresult = "\\Seventy" . $cresult if $ten == 7;
				$cresult = "\\Eighty" . $cresult if $ten == 8;
				$cresult = "\\Ninety" . $cresult if $ten == 9;
			}
		}
	}								
	#$cresult = "\\shoveright " . $cresult;
	return $cresult;
}

sub print_abstractmatrix {
	 my ($t) = @_;
	$abstractmatrices[$t] = "";
	foreach my $n (1..$N) {
		foreach my $m (1..$N) {
			if ($n == $N and $m == 1) {
				$abstractmatrices[$t] .= qq{ l_{$N} & };
			}elsif ($n == $N and $m <= $t + 1) {
				if ($m % 2 == 0 ) {
					$abstractmatrices[$t] .= qq{ - };
				};
				my $r = $m -1;
				$abstractmatrices[$t] .= qq{ l_{$N} };
				foreach my $i (1..$t -1) {
					if ($i < $m -1 ) {
						$abstractmatrices[$t] .= qq{ l_{$i}  };
					}
				}
				$abstractmatrices[$t] .= qq{ l_{$r} & };
			}elsif ($m == $n) {
				$abstractmatrices[$t] .= qq{ k_{$n} & };
			}elsif ($m == $n+1) {
				$abstractmatrices[$t] .= qq{ l_{$n} & };
			}else{
				$abstractmatrices[$t] .= qq{ 0 & };
			}; 
		};
		$abstractmatrices[$t] .= qq{ b_{$n} \\\\  };
	};
	return $abstractmatrices[$t];
}

sub print_a {
	$print_a = qq{<table>};
	my $format = "";
	my $i = 0;		
	foreach my $n (1..$N) {
			$print_a .= qq{<tr>};
			foreach my $m (1..$N) {
			if (($m == $n+1) or ($m == $n) or ($m == 1 and $n == $N)) {
				$print_a .= qq{<td><input type="text" name="b[$n][$m]" default value="$b{$n}{$m}" align="center" size="7" maxlength="7" border="0"></td>};
			}else{
				$print_a .= qq{<td>0</td>};
			}
		};
		$print_a .= qq{<td><input type="text" name="b[$n][$M]" default value="$b{$n}{$M}" size="10" maxlength="10" border="0" align="center"></td>};
		$print_a .= qq{</tr>};
	};
	$print_a .= qq{</table>};
	return $print_a;
};

sub print_matrix {
	$matrix = "";
	foreach my $n (1..$N) {
		foreach my $m (1..$N) {
			$matrix .= qq{ $a{$n}{$m} & };
		};
		$matrix .= qq{ $a{$n}{$M} \\\\ };
	};
	return $matrix;
}

sub print_cmatrix {
	$cmatrix = "";
	unless ($noninteger){
		foreach my $m (1..$M) {
			foreach my $n (reverse (2..$N)) {
				$cmatrix .= qq{ $c{$n}{$m} ~ \\vline ~ & };
			};
			$cmatrix .= qq{ $c{1}{$m} \\\\  };
			unless ($m == $M) {$cmatrix .= qq{  \\hline   }};
		};
	};
	return $cmatrix;
};

#PRINT HTML SUBROUTINES

sub print_header {	# style = "font-size: 12px; font-family: 'Impact'; background-color : yellow;  font-weight : bold;  font-size: 12px; font-family: 'Helvetica'; text-decoration : underline"
	my $print_header = qq{ 
		<style type="text/css">
		p {font-family: serif; font-weight: lighter;}
		h3 {font-family: Arial Arial Black; font-weight: bolder; }
		th {font-family: Arial Arial Black; font-size: small; text-align: center; vertical-align: bottom; border-collapse: collapse; border-spacing: 0px 0px;}
		td {font-family: Arial Arial Black; text-align: center; vertical-align: center; border-collapse: collapse; border-spacing: 0px 0px; width: 5em}
		table {border-collapse: separate; border-spacing: 0px 1px; border: 1px solid black; table-layout: fixed; font-color: blue; } 
		</style> }; 	# background-color: #bbf
	# 	$print_header .= qq{<tr><th colspan = "1"></th>};
	# 	foreach my $m (@m) {
	# 		$print_header .= qq{<th colspan = "1">$m</th>};
	# 	};
	#	$print_header .= qq{</tr>};
};

#PRINT LATEX OUTPUT
# 	{\setlength{\arrayrulewidth}{0.05pt} %default is 0.4pt
#   \setlength{\arraycolsep}{2pt}%default is 5pt
#  \renewcommand{\arraystretch}{1.2}%default is 1

sub createout1 {
	foreach my $i (0..$N-2){
		$output .= qq{
			<p></p>
			<h4>Step $i<\h4>
			<p>$boardnotes[$i]</p>
			<p><img src="../cgi-bin/mathtex.cgi?
			\\renewcommand{\\arraystretch}{2}
			\\setlength{\\arrayrulewidth}{0.05pt}
			\\fbox{
			\\begin{equation*}
			\\begin{array}{*{$N}r}
				$cmatrices[$i]
			\\end{array} 
			\\end{equation*}
			}
			" alt="" border=0 align=middle>
			$calcnotes[$i] 
			<p>
			<img src="../cgi-bin/mathtex.cgi?
			\\usepackage{euler}
			\\begin{equation*}
			\\begin{bmatrix}
				$matrices[$i]
			\\end{bmatrix}
			\\end{equation*}
			" alt="" border=0 align=middle>
			<p>
			$formulanotes[$i] 
			<img src="../cgi-bin/mathtex.cgi?
			\\usepackage{euler}
			\\begin{equation*}
			\\begin{bmatrix}
				$abstractmatrices[$i]
			\\end{bmatrix}
			\\end{equation*}
			" alt="" border=0 align=middle>
			<p>
		};
	}
	return $output;
}

sub createout2 {
	foreach my $i ($N..2*$N-2){
		$output .= qq{
			<p>
			<h4>Step $i<\h4>
			<p>
			<img src="../cgi-bin/mathtex.cgi?
			\\usepackage{scalefnt}
			\\scalefont{1}
			\\fbox{
			\\begin{equation*}
			\\begin{array}{*{$N}r}
				$cresult[$i+1-$N]
			\\end{array} 
			\\end{equation*}
			}
			" alt="" border=0 align=middle>
			<p>
			<img src="../cgi-bin/mathtex.cgi?
			\\usepackage{euler}
			\\begin{equation*}
				$result[$i+1-$N]
			\\end{equation*}
			" alt="" border=0 align=middle>
			<p>
			<img src="../cgi-bin/mathtex.cgi?
			\\usepackage{euler}
			\\begin{equation*}
				$formula[$i]
			\\end{equation*}
			" alt="" border=0 align=middle>
			<p>
		};
	}
	return $output;
}

sub createout3 {
	my $laststep = 2*$N-1;
	$output .= qq{
		<p>
		<h4>Step $laststep<\h4>
		<p>
		<img src="../cgi-bin/mathtex.cgi?
		\\usepackage{euler}
		\\begin{equation*}
			$result[$N]
		\\end{equation*}
		" alt="" border=0 align=middle>
		 <p>
		<img src="../cgi-bin/mathtex.cgi?
		\\usepackage{euler}
		\\begin{equation*}
			$formula[2*$N]
		\\end{equation*}
		" alt="" border=0 align=middle>
		<p>
	};
	return $output;
}

#CGI SUBROUTINES

sub choose_options {	
	if ($query->param('JZSSnum') && ($query->param('JZSSnum') != $JZSSnum)) {
		$JZSSnum = $query->param('JZSSnum');
		&JZSS($JZSSnum);
	}elsif (0==1){ # ($query->param('N') && ($query->param('N') != $N)) {
		$N = $query->param('N');
		unless (($N >= 1) and ($N <= 5)) {$N = 3};
		$M = $N + 1;
		&random_a;
	}else{
		$JZSSnum = $query->param('OldJZSSnum'); #= $query->param("N");
		$N = $query->param('N'); #= $query->param("N");
		$error .= " <p>My old N is $N </p>";
		$M = $N+1;
		foreach my $n (1..$N) {
			foreach my $m (1..$M) {
				if (($m == $n+1) or ($m == $n) or ($m == 1 and $n == $N) or $m == $M) {
					my $input = $query->param("b[$n][$m]");
					$input =~ s/\s+//g;
					if ($input =~ m/^\-?\d+(\/\d+)?$/) {
 						$b{$n}{$m} = $input;
 					}else{
 						$inputerror .= qq{<p>"$input" is not valid input. Entries must be an integer or a proper fraction. };
  						if ($input =~ m/\-?\d+(\/\d+)?/) {
  	 						$b{$n}{$m} = $&;					
  						}else{
  				 			$b{$n}{$m} = 0;
 						}						
 						$inputerror .= qq{The entry has been set to $b{$n}{$m}.</p>};
 					}
				}
				$JZSS[$JZSSnum][$n-1][$m-1] = "$b{$n}{$m}";
			}
		}
		&JZSS($JZSSnum);
	}
	if ($query->param('usegcf')) {
		$usegcf = $query->param('usegcf');
		unless ($usegcf == 1) {$usegcf = 0};
	}
}

#PRINT HTML PAGE

print $query->header, 
	$query->start_html('Chinese linear algebra'), 
	h2('Elimination'),
	p,
	start_form,
	hr,
	"Problem:",  popup_menu(-name=>'JZSSnum', -values=>\@JZSSproblems, -default=>""),p,
	submit(-name=>'Choose new problem'),
	p,
	end_form;
$query->end_html; 


#PROCESS SUBROUTINES
if ($query->param()) {
	&choose_options;
	$table_a = &print_a; 
	$table_header = &print_header; 
	&rowReduction;
	&backSubstitution;
	&divideANN;
	#&determinants;
	&createout1;
	&createout2;
	&createout3;	
	print 
		start_form,
		hr,
		hidden(-name=>'N', -default=>["$N"]),
		hidden(-name=>'OldJZSSnum', -default=>["$JZSSnum"]),
		p, $table_header, $table_a, p,
		submit(-name=>'Recalculate with new values'), p,
		"$inputerror",
		p,
		# reset(-name=>'Reset to original values'), p,
		hr,
		end_form;
			my $output = "";
	
	# 		\\usepackage{scalefnt}
	# 		\\scalefont{1}
	
	
	foreach my $i (0..$N-1){
		$output .= qq{
			<p>
			<h4>Step $i<\h4>
			<p>
			<img src="../cgi-bin/mathtex.cgi?
			\\usepackage{graphicx}
			\\renewcommand{\\arraystretch}{2}
			\\setlength{\\arrayrulewidth}{0.05pt}
			\\scalebox{.5}{
			\\fbox{
			\\begin{equation*}
			\\begin{array}{*{$N}r}
				$cmatrices[$i]
			\\end{array} 
			\\end{equation*}
			}}
			" alt="" border=0 align=middle>
			<p>
			<img src="../cgi-bin/mathtex.cgi?
			\\usepackage{euler}
			\\begin{equation*}
			\\begin{bmatrix}
				$matrices[$i]
			\\end{bmatrix}
			\\end{equation*}
			" alt="" border=0 align=middle>
			<p>
			};
	}
	foreach my $i ($N+1..2*$N-1){
		my $j = $i-1;
		$output .= qq{
			<p>
			<h4>Step $j<\h4>
			<p>
			<img src="../cgi-bin/mathtex.cgi?
			\\usepackage{graphicx}\n
			\\renewcommand{\\arraystretch}{2}
			\\setlength{\\arrayrulewidth}{0.05pt}
			\\scalebox{.5}{
			\\fbox{
			\\begin{equation*}
			\\begin{array}{*{$N}r}
				$cmatrices[$i]
			\\end{array} 
			\\end{equation*}
			}}
			" alt="" border=0 align=middle>
			<p>
			<img src="../cgi-bin/mathtex.cgi?
			\\usepackage{euler}
			\\begin{equation*}
			\\begin{bmatrix}
				$matrices[$i]
			\\end{bmatrix}
			\\end{equation*}
			" alt="" border=0 align=middle>
			<p>
			};
	}
	foreach my $i (2*$N..3*$N-1){
		my $j = $i-1;
		$output .= qq{
			<p>
			<h4>Step $j<\h4>
			<p>
			<img src="../cgi-bin/mathtex.cgi?
			\\usepackage{euler}
			\\begin{equation*}
			\\begin{bmatrix}
				$matrices[$i]
			\\end{bmatrix}
			\\end{equation*}
			" alt="" border=0 align=middle>
			<p>
			};
	}
	print qq{$output};
	
	$query->end_html; 
	#$query->delete_all();
}


# 	my @names = $query->param;
# 	$error .="@names ";
# 	
# 	my $params = $query->Vars;
# 	print $params->{'address'};
# 	my @foo = split("\0",$params->{'foo'});
# 	my %params = $query->Vars;
# 	use CGI ':cgi-lib';
# 	$params = Vars;
# 	$error .="$params";
# 	foreach my $key (%params) {
# 		$error .= "<p>$key => $params{$key}</p>";
# 	}
# 	print qq{$error};


